home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Python 1.4 / Python 1.4 source / Extensions / img / imgxxxmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  10.4 KB  |  412 lines  |  [TEXT/CWIE]

  1. /***********************************************************
  2. Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
  3. Amsterdam, The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* Use this file as a template to start implementing a new image file
  26.    type module. If you are creating a module to support image files of
  27.    type 'foo', copy to imgfoomodule.c, and replace all occurrences of
  28.    'xxx' by 'foo'. (XXX stands for 'Generic IMage', by the way).
  29.  
  30.    The intended semantics of using an image reader are as follows:
  31.        import imgxxx
  32.        rdr = imgxxx.newreader('filename')
  33.        x = rdr.x
  34.        y = rdr.y
  35.        data = rdr.read()
  36.    and, for the writer:
  37.        wrr = imgxxx.newwriter('filename')
  38.        wrr.x = x
  39.        wrr.y = y
  40.        wrr.write(data)
  41.    So, to summarize, opening a reader reads the header and stores all
  42.    interesting information in the attributes (which are kept in the 'dict'
  43.    member of the xxxobject structure). For a writer the situation is slightly
  44.    different since the header is written at the write() call.
  45.  
  46.    The routine xxxselfattr() allows you to easily obtain values from the
  47.    attributes.
  48.  
  49.    The following routines need massaging:
  50.    - initxxxreader() and initxxxwriter(), and possibly
  51.      xxx_newreader() and xxx_newwriter() (if you need extra args),
  52.    - delxxxreaderobject() and delxxxwriterobject()
  53.    - xxx_read() and xxx_write().
  54. */
  55.  
  56. /* Xxx objects */
  57.  
  58. #include "Python.h"
  59. #include "import.h"
  60.  
  61. /* XXXX change this to the image formats we support */
  62.  
  63. static PyObject *format_rgb, *format_rgb_b2t, *format_choices;
  64. extern PyObject *getimgformat();    /* Get foirmat by name */
  65.  
  66. typedef struct {
  67.     PyObject_HEAD
  68.     PyObject    *dict;        /* Attributes dictionary */
  69.     int    is_reader;    /* TRUE if this is a reader */
  70.     char    *filename;    /* filename of the image file */
  71.     /* Add other (user-invisible) data here */
  72. } xxxobject;
  73.  
  74. static PyObject *errobject;
  75.  
  76. staticforward PyTypeObject Xxxtype;
  77.  
  78. #define is_xxxobject(v)        ((v)->ob_type == &Xxxtype)
  79.  
  80. static char doc_xxx[] =
  81.     "This object can be used to read/write xxximage files.\n"
  82.     "The 'width', 'height' and 'format' attributes give info about the\n"
  83.     "image data read (or to be written)";
  84.  
  85. /* Routine to easily obtain C data from the dict python data */
  86. int
  87. xxxselfattr(self, name, fmt, ptr, wanterr)
  88.     xxxobject *self;
  89.     char *name;
  90.     char *fmt;
  91.     void *ptr;
  92.     int wanterr;
  93. {
  94.     PyObject *obj;
  95.     char errbuf[100];
  96.  
  97.     obj = PyDict_GetItemString(self->dict, name);
  98.     if ( obj == NULL ) {
  99.     if ( wanterr ) {
  100.         sprintf(errbuf, "Required attribute '%s' not set", name);
  101.         PyErr_SetString(errobject, errbuf);
  102.         return 0;
  103.     } else {
  104.         PyErr_Clear();
  105.         return 0;
  106.     }
  107.     }
  108.     if ( !PyArg_Parse(obj, fmt, ptr) ) {
  109.     if ( !wanterr )
  110.         PyErr_Clear();
  111.     return 0;
  112.     }
  113.     return 1;
  114. }
  115.  
  116. /* Routine to easily insert integer into dictionary */
  117. xxxsetintattr(self, name, value)
  118.     xxxobject *self;
  119.     char *name;
  120.     int value;
  121. {
  122.     PyObject *obj;
  123.     int rv;
  124.  
  125.     obj = PyInt_FromLong(value);
  126.     rv = PyDict_SetItemString(self->dict, name, obj);
  127.     Py_DECREF(obj);
  128.     return rv;
  129. }
  130.  
  131. static xxxobject *
  132. newxxxobject()
  133. {
  134.     xxxobject *xp;
  135.     xp = PyObject_NEW(xxxobject, &Xxxtype);
  136.     if (xp == NULL)
  137.         return NULL;
  138.     xp->dict = PyDict_New();
  139.     xp->filename = NULL;
  140.     /* XXXX Initialize other pointers here as well */
  141.     return xp;
  142. }
  143.  
  144. static int
  145. initxxxreader(self, name)
  146.     xxxobject *self;
  147.     char *name;
  148. {
  149.     char *name_copy;
  150.  
  151.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  152.     PyErr_NoMemory();
  153.     return 0;
  154.     }
  155.     strcpy(name_copy, name);
  156.     self->filename = name_copy;
  157.     self->is_reader = 1;
  158.     /* XXXX Open image file, read header, put into dict: */
  159.     xxxsetintattr(self, "width", 0);
  160.     xxxsetintattr(self, "height", 0);
  161.     PyDict_SetItemString(self->dict, "format", format_rgb);
  162.     PyDict_SetItemString(self->dict, "format_choices", format_choices);
  163.     if( PyErr_Occurred() )
  164.     return 0;
  165.     return 1;
  166. }
  167.  
  168. static int
  169. initxxxwriter(self, name)
  170.     xxxobject *self;
  171.     char *name;
  172. {
  173.     char *name_copy;
  174.  
  175.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  176.     PyErr_NoMemory();
  177.     return 0;
  178.     }
  179.     strcpy(name_copy, name);
  180.     self->filename = name_copy;
  181.     self->is_reader = 0;
  182.     PyDict_SetItemString(self->dict, "format", format_rgb);
  183.     PyDict_SetItemString(self->dict, "format_choices", format_choices);
  184.     if( PyErr_Occurred())
  185.     return 0;
  186.     return 1;
  187. }
  188.  
  189. /* Xxx methods */
  190.  
  191. static void
  192. xxx_dealloc(xp)
  193.     xxxobject *xp;
  194. {
  195.     Py_XDECREF(xp->dict);
  196.     if( xp->filename )
  197.         free(xp->filename);
  198.     /* XXXX Free other allocated things here */
  199.     PyMem_DEL(xp);
  200. }
  201.  
  202. static char doc_read[] = "Read the actual image data as a string";
  203.  
  204. static PyObject *
  205. xxx_read(self, args)
  206.     xxxobject *self;
  207.     PyObject *args;
  208. {
  209.         PyObject *fmt;
  210.     
  211.     if (!PyArg_ParseTuple(args,""))
  212.         return NULL;
  213.     if (!self->is_reader) {
  214.         PyErr_SetString(errobject, "Cannot read() from writer object");
  215.         return NULL;
  216.     }
  217.     /* XXXX Get format (and other args), check, read data, return it */
  218.     if ( !xxxselfattr(self, "format", "O", &fmt, 1) )
  219.         return NULL;
  220.     if ( fmt == format_rgb ) {
  221.         /* XXXX do one thing */
  222.     } else {
  223.         /* XXXX do something else */
  224.     }
  225.     return PyString_FromString("");
  226. }
  227.  
  228. static char doc_write[] = "Write the image data";
  229.  
  230. static PyObject *
  231. xxx_write(self, args)
  232.     xxxobject *self;
  233.     PyObject *args;
  234. {
  235.         char *data;
  236.     int datalen;
  237.     int w, h;
  238.     
  239.     if (!PyArg_ParseTuple(args, "s#", &data, &datalen))
  240.         return NULL;
  241.     if (self->is_reader) {
  242.         PyErr_SetString(errobject, "Cannot write() to reader object");
  243.         return NULL;
  244.     }
  245.     /* XXXX Get args from self->dict and write the data */
  246.     if ( !xxxselfattr(self, "width", "i", &w, 1) ||
  247.          !xxxselfattr(self, "height", "i", &h, 1) )
  248.         return NULL;
  249.     if( w*h != datalen ) {
  250.         PyErr_SetString(errobject, "Incorrect datasize");
  251.         return NULL;
  252.     }
  253.     Py_INCREF(Py_None);
  254.     return Py_None;
  255. }
  256.  
  257. static struct PyMethodDef xxx_methods[] = {
  258.     {"read",    (PyCFunction)xxx_read,    1,    doc_read},
  259.     {"write",    (PyCFunction)xxx_write,    1,    doc_write},
  260.     {NULL,        NULL}        /* sentinel */
  261. };
  262.  
  263. static PyObject *
  264. xxx_getattr(xp, name)
  265.     xxxobject *xp;
  266.     char *name;
  267. {
  268.         PyObject *v;
  269.     
  270.     if (xp->dict != NULL) {
  271.             if ( strcmp(name, "__dict__") == 0 ) {
  272.                 Py_INCREF(xp->dict);
  273.             return xp->dict;
  274.         }
  275.         if ( strcmp(name, "__doc__") == 0 ) {
  276.                 return PyString_FromString(doc_xxx);
  277.         }
  278.         v = PyDict_GetItemString(xp->dict, name);
  279.         if (v != NULL) {
  280.             Py_INCREF(v);
  281.             return v;
  282.         }
  283.     }
  284.     return Py_FindMethod(xxx_methods, (PyObject *)xp, name);
  285. }
  286.  
  287. static int
  288. xxx_setattr(xp, name, v)
  289.     xxxobject *xp;
  290.     char *name;
  291.     PyObject *v;
  292. {
  293.     if (xp->dict == NULL) {
  294.         xp->dict = PyDict_New();
  295.         if (xp->dict == NULL)
  296.             return -1;
  297.     }
  298.     if (v == NULL) {
  299.         int rv = PyDict_DelItemString(xp->dict, name);
  300.         if (rv < 0)
  301.             PyErr_SetString(PyExc_AttributeError,
  302.                     "delete non-existing imgxxx attribute");
  303.         return rv;
  304.     }
  305.     else
  306.         return PyDict_SetItemString(xp->dict, name, v);
  307. }
  308.  
  309. static PyTypeObject Xxxtype = {
  310.     PyObject_HEAD_INIT(&PyType_Type)
  311.     0,            /*ob_size*/
  312.     "imgxxx",        /*tp_name*/
  313.     sizeof(xxxobject),    /*tp_basicsize*/
  314.     0,            /*tp_itemsize*/
  315.     /* methods */
  316.     (destructor)xxx_dealloc, /*tp_dealloc*/
  317.     0,            /*tp_print*/
  318.     (getattrfunc)xxx_getattr, /*tp_getattr*/
  319.     (setattrfunc)xxx_setattr, /*tp_setattr*/
  320.     0,            /*tp_compare*/
  321.     0,            /*tp_repr*/
  322.     0,            /*tp_as_number*/
  323.     0,            /*tp_as_sequence*/
  324.     0,            /*tp_as_mapping*/
  325.     0,            /*tp_hash*/
  326. };
  327.  
  328. static char doc_newreader[] = "Create reader for file passed as arg";
  329.  
  330. static PyObject *
  331. xxx_newreader(self, args)
  332.     PyObject *self;
  333.     PyObject *args;
  334. {
  335.         char *filename;
  336.     xxxobject *obj;
  337.     
  338.     if (!PyArg_ParseTuple(args, "s", &filename))
  339.         return NULL;
  340.     if ((obj = newxxxobject()) == NULL)
  341.         return NULL;
  342.     if ( !initxxxreader(obj, filename) ) {
  343.         xxx_dealloc(obj);
  344.         return NULL;
  345.     }
  346.     return (PyObject *)obj;
  347. }
  348.  
  349. static char doc_newwriter[] = "Create writer for file passed as arg";
  350.  
  351. static PyObject *
  352. xxx_newwriter(self, args)
  353.     PyObject *self;
  354.     PyObject *args;
  355. {
  356.         char *filename;
  357.     xxxobject *obj;
  358.     
  359.     if (!PyArg_ParseTuple(args, "s", &filename))
  360.         return NULL;
  361.     if ((obj = newxxxobject()) == NULL)
  362.         return NULL;
  363.     if ( !initxxxwriter(obj, filename) ) {
  364.         xxx_dealloc(obj);
  365.         return NULL;
  366.     }
  367.     return (PyObject *)obj;
  368. }
  369.  
  370.  
  371. /* List of functions defined in the module */
  372.  
  373. static struct PyMethodDef xxx_module_methods[] = {
  374.     {"reader",    xxx_newreader,    1,    doc_newreader},
  375.     {"writer",    xxx_newwriter,    1,    doc_newwriter},
  376.     {NULL,        NULL}        /* sentinel */
  377. };
  378.  
  379.  
  380. /* Initialization function for the module (*must* be called initimgxxx) */
  381. static char doc_imgxxx[] = "Boilerplate for image file access modules";
  382.  
  383. void
  384. initimgxxx()
  385. {
  386.     PyObject *m, *d, *x, *formatmodule, *formatdict;
  387.  
  388.     /* Create the module and add the functions */
  389.     m = Py_InitModule("imgxxx", xxx_module_methods);
  390.  
  391.     /* Add some symbolic constants to the module */
  392.     d = PyModule_GetDict(m);
  393.     errobject = PyString_FromString("imgxxx.error");
  394.     PyDict_SetItemString(d, "error", errobject);
  395.     x = PyString_FromString(doc_imgxxx);
  396.     PyDict_SetItemString(d, "__doc__", x);
  397.  
  398.     /* Get supported formats */
  399.     if ((formatmodule = PyImport_ImportModule("imgformat")) == NULL)
  400.         Py_FatalError("imgxxx depends on imgformat");
  401.     if ((formatdict = PyModule_GetDict(formatmodule)) == NULL)
  402.         Py_FatalError("imgformat has no dict");
  403.  
  404.     format_rgb = PyDict_GetItemString(formatdict,"rgb");
  405.     format_rgb_b2t = PyDict_GetItemString(formatdict,"rgb_b2t");
  406.     format_choices = Py_BuildValue("(OO)", format_rgb, format_rgb_b2t);
  407.  
  408.     /* Check for errors */
  409.     if (PyErr_Occurred())
  410.         Py_FatalError("can't initialize module imgxxx");
  411. }
  412.